/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package PackageInstaller.MainUi;

import PackageInstaller.Config.*;
import java.awt.Font;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import javax.swing.*;

/**
 * LanguageArrays.getLanguageText(currentLanguage, "001")
 *
 * @author wcss
 */
public class JInstallerMainFrame extends javax.swing.JFrame implements Runnable {

    private File xmlConfig = null;
    private File dataDir = null;
    private PackageInstallerConfig config = null;
    public static String currentLanguage = "english";
    private int currentInstallStep = 1;
    private ArrayList<FileCopyItem> copyRootFiles = new ArrayList<FileCopyItem>();
    private ArrayList<FileCopyItem> copyHomeFiles = new ArrayList<FileCopyItem>();
    //LanguageArrays.getLanguageText(currentLanguage, "001")

    /**
     * Creates new form JInstallerMainFrame
     */
    public JInstallerMainFrame(String xml, String data) throws Exception {
        initComponents();
        this.xmlConfig = new File(xml);
        this.dataDir = new File(data);
        if (xmlConfig.exists() && dataDir.exists()) {
            config = PackageInstallerConfig.load(xmlConfig.getAbsolutePath());
            this.loadConfig();
        } else {
            javax.swing.JOptionPane.showMessageDialog(null, LanguageArrays.getLanguageText(currentLanguage, "001"));
            System.exit(0);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblOnlyRead = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtContent = new javax.swing.JTextArea();
        btnNext = new javax.swing.JButton();
        btnExit = new javax.swing.JButton();
        image = new PackageInstaller.BaseUI.JImagePanel("/PackageInstaller/BaseUI/logo.png");
        lblFlag = new javax.swing.JLabel();
        lblWelcome = new javax.swing.JLabel();
        progress = new javax.swing.JProgressBar();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setResizable(false);

        lblOnlyRead.setFont(new java.awt.Font("文泉驿微米黑", 1, 16)); // NOI18N
        lblOnlyRead.setText("安装前说明：");

        txtContent.setEditable(false);
        txtContent.setColumns(20);
        txtContent.setFont(new java.awt.Font("文泉驿微米黑", 0, 12)); // NOI18N
        txtContent.setRows(5);
        jScrollPane1.setViewportView(txtContent);

        btnNext.setFont(new java.awt.Font("文泉驿微米黑", 1, 12)); // NOI18N
        btnNext.setText("下一步");
        btnNext.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNextActionPerformed(evt);
            }
        });

        btnExit.setFont(new java.awt.Font("文泉驿微米黑", 1, 12)); // NOI18N
        btnExit.setText("退出");
        btnExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnExitActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout imageLayout = new javax.swing.GroupLayout(image);
        image.setLayout(imageLayout);
        imageLayout.setHorizontalGroup(
            imageLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 177, Short.MAX_VALUE)
        );
        imageLayout.setVerticalGroup(
            imageLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 382, Short.MAX_VALUE)
        );

        lblFlag.setFont(new java.awt.Font("文泉驿微米黑", 1, 20)); // NOI18N
        lblFlag.setText("None");

        lblWelcome.setFont(new java.awt.Font("文泉驿微米黑", 1, 20)); // NOI18N
        lblWelcome.setText("None");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(12, 12, 12)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lblFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 177, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(22, 22, 22)
                        .addComponent(lblOnlyRead, javax.swing.GroupLayout.PREFERRED_SIZE, 484, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(image, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(12, 12, 12)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 502, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(progress, javax.swing.GroupLayout.PREFERRED_SIZE, 502, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lblWelcome, javax.swing.GroupLayout.PREFERRED_SIZE, 463, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(12, 12, 12)
                        .addComponent(btnNext, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(6, 6, 6)
                        .addComponent(btnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblFlag)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(3, 3, 3)
                        .addComponent(lblOnlyRead, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(image, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 349, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(6, 6, 6)
                        .addComponent(progress, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblWelcome)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(2, 2, 2)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(btnNext)
                            .addComponent(btnExit))))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed
        // TODO add your handling code here:
        int option = JOptionPane.showConfirmDialog(null, getLangTxt("007"), "", JOptionPane.YES_NO_OPTION);
        if (option == JOptionPane.YES_OPTION) {
            System.exit(0);
        }
    }//GEN-LAST:event_btnExitActionPerformed

    private void btnNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNextActionPerformed
        // TODO add your handling code here:
        if (this.currentInstallStep == 1) {
            this.lblOnlyRead.setText(getLangTxt("010"));
            clearLogs();
            printLogs(getLangTxt("011") + this.config.getPackageName());
            printLogs(getLangTxt("012") + this.config.getHomepage());
            printLogs(getLangTxt("013") + this.config.getManager());
            printLogs("\n");
            printFileList();
            this.btnNext.setText(getLangTxt("016"));
        } else if (this.currentInstallStep == 2) {
            try {
                clearLogs();
                writeCopyRootFileScript();
                writeCopyHomeFileScript();
                this.btnNext.setEnabled(false);
                startInstall();
            } catch (Exception ex) {
                ex.printStackTrace();
                javax.swing.JOptionPane.showMessageDialog(null, LanguageArrays.getLanguageText(currentLanguage, "001"));
                System.exit(0);
            }

        } else if (this.currentInstallStep >= 3) {
            System.exit(0);
        }

        this.currentInstallStep++;
    }//GEN-LAST:event_btnNextActionPerformed

    private void startInstall()
    {
        Thread tt = new Thread(this);
        progress.setMaximum(3);
        progress.setValue(0);
        tt.setDaemon(true);
        tt.start();
    }

    private void writeCopyRootFileScript() throws Exception {
        File ff = new File(this.dataDir.getAbsolutePath() + "/copyRootFilesTo.sh");
        ArrayList<String> list = new ArrayList<String>();

        for (FileCopyItem fci : this.copyRootFiles) {
            File ee = new File(fci.getDest());
            if (!ee.getParentFile().exists()) {
                if (!list.contains("mkdir --parents " + ee.getParent())) {
                    list.add("mkdir --parents " + ee.getParent());
                }
            }
        }
        for (FileCopyItem fci : this.copyRootFiles) {
            list.add("cp " + fci.getSource() + " " + fci.getDest());
        }
        JAppToolKit.JDataHelper.writeAllLines(ff.getAbsolutePath(), list);
    }

    private void writeCopyHomeFileScript() throws Exception {
        File ff = new File(this.dataDir.getAbsolutePath() + "/copyHomeFilesTo.sh");
        ArrayList<String> list = new ArrayList<String>();

        for (FileCopyItem fci : this.copyHomeFiles) {
            File ee = new File(fci.getDest());
            if (!ee.getParentFile().exists()) {
                if (!list.contains("mkdir --parents " + ee.getParent())) {
                    list.add("mkdir --parents " + ee.getParent());
                }
            }
        }
        for (FileCopyItem fci : this.copyHomeFiles) {
            list.add("cp " + fci.getSource() + " " + fci.getDest());
        }
        JAppToolKit.JDataHelper.writeAllLines(ff.getAbsolutePath(), list);
    }

    private String getDesktopDir() {
        File dirConfig = new File(JAppToolKit.JRunHelper.getUserHomeDirPath() + "/.config/user-dirs.dirs");
        if (dirConfig.exists()) {
            try {
                String result = "";
                String[] teams = JAppToolKit.JDataHelper.readAllLines(dirConfig.getAbsolutePath());
                for (String s : teams) {
                    if (s.startsWith("XDG_DESKTOP_DIR=")) {
                        result = s.replace("\"", "").replace("'", "").replace("XDG_DESKTOP_DIR=", "").replace("$HOME/", JAppToolKit.JRunHelper.getUserHomeDirPath() + "/");
                        break;
                    }
                }
                return result.trim();
            } catch (Exception ex) {
                Logger.getLogger(JInstallerMainFrame.class.getName()).log(Level.SEVERE, null, ex);
                return "";
            }
        } else {
            return "";
        }
    }

    private void searchFiles(File base, File dir) {
        if (dir.exists()) {
            File[] files = dir.listFiles();
            if (dir.isFile()) {
                String sources = dir.getAbsolutePath();
                String dests = dir.getAbsolutePath().replace(base.getAbsolutePath(), "");
                if (dests.startsWith("/%HOME%")) {
                    dests = dests.replace("/%HOME%", JAppToolKit.JRunHelper.getUserHomeDirPath());
                    copyHomeFiles.add(new FileCopyItem(sources, dests, true));
                } else if (dests.startsWith("/%DESKTOP%")) {
                    String desktops = getDesktopDir();
                    if (desktops.equals("")) {
                        dests = dests.replace("/%DESKTOP%", JAppToolKit.JRunHelper.getUserHomeDirPath());
                        copyHomeFiles.add(new FileCopyItem(sources, dests, true));
                    } else {
                        dests = dests.replace("/%DESKTOP%", desktops);
                        copyHomeFiles.add(new FileCopyItem(sources, dests, true));
                    }

                } else {
                    copyRootFiles.add(new FileCopyItem(sources, dests, true));
                }
            }
            if (files != null) {
                for (File f : files) {
                    searchFiles(base, f);
                }
            }
        }
    }

    private void printFileList() {
        this.copyRootFiles.clear();
        this.copyHomeFiles.clear();
        searchFiles(new File(this.dataDir.getAbsolutePath() + "/data"), new File(this.dataDir.getAbsolutePath() + "/data"));

        printLogs(getLangTxt("014"));
        for (FileCopyItem fci : copyRootFiles) {
            printLogs(fci.toString());
        }

        printLogs(getLangTxt("015"));
        for (FileCopyItem fci : copyHomeFiles) {
            printLogs(fci.toString());
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        final String[] param = args;
        if (args.length >= 2) {

            if (args[0] != null && (args[0].equals("english") || args[0].equals("chinese"))) {
                currentLanguage = args[0];
            } else {
                currentLanguage = "english";
            }
            /* Set the Nimbus look and feel */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
             * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if (javax.swing.UIManager.getCrossPlatformLookAndFeelClassName().equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }

//                if (currentLanguage != null && currentLanguage.equals("chinese")) {
                Font f = new Font("文泉驿微米黑", Font.PLAIN, 12);
                UIManager.put("OptionPane.messageFont", f);
                UIManager.put("OptionPane.buttonFont", f);
//                }
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(JInstallerMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>

            /* Create and display the form */
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        JInstallerMainFrame frame = new JInstallerMainFrame(param[1] + "/config.xml", param[1]);
                        frame.setResizable(false);
                        //frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
                        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                        frame.setVisible(true);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        javax.swing.JOptionPane.showMessageDialog(null, LanguageArrays.getLanguageText(currentLanguage, "001"));
                        System.exit(0);
                    }
                }
            });
        } else {
            javax.swing.JOptionPane.showMessageDialog(null, LanguageArrays.getLanguageText(currentLanguage, "001"));
            System.exit(0);
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnExit;
    private javax.swing.JButton btnNext;
    private PackageInstaller.BaseUI.JImagePanel image;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblFlag;
    private javax.swing.JLabel lblOnlyRead;
    private javax.swing.JLabel lblWelcome;
    private javax.swing.JProgressBar progress;
    private javax.swing.JTextArea txtContent;
    // End of variables declaration//GEN-END:variables

    public static String getLangTxt(String code) {
        return LanguageArrays.getLanguageText(currentLanguage, code);
    }

    private void printLogs(String txts) {
        this.txtContent.setText(this.txtContent.getText() + txts + "\n");
    }

    private void clearLogs() {
        this.txtContent.setText("");
    }

    private void loadConfig() {
        //LanguageArrays.getLanguageText(currentLanguage, "001")
        this.setTitle(getLangTxt("002") + this.config.getTitleText() + "   " + getLangTxt("006") + this.config.getPackageVersion());
        this.lblFlag.setText(this.config.getTopFlag());
        this.lblWelcome.setText(this.config.getWelcome());
        this.lblOnlyRead.setText(getLangTxt("003"));
        this.btnNext.setText(getLangTxt("004"));
        this.btnExit.setText(getLangTxt("005"));

        clearLogs();
        try {
            String[] licenses = JAppToolKit.JDataHelper.readAllLines(this.dataDir + "/" + this.config.getLicenseFile());
            for (String s : licenses) {
                printLogs(s);
            }
        } catch (Exception ex) {
            Logger.getLogger(JInstallerMainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }

        File ff = new File(this.dataDir + "/" + this.config.getLogoImage());
        if (ff.exists()) {
            image.setBackgroundImage(new ImageIcon(ff.getAbsolutePath()));
        }
    }

    public void runScriptWithOutput(String scriptFile) throws Exception {
        JAppToolKit.JRunHelper.runSysCmd("chmod +x " + scriptFile);

        Process pro = JAppToolKit.JRunHelper.runSysCmd(scriptFile, false);
        BufferedReader errors = new BufferedReader(new InputStreamReader(pro.getErrorStream()));
        BufferedReader results = new BufferedReader(new InputStreamReader(pro.getInputStream()));
        pro.waitFor();

        printLogs("------");
        printLogs(getLangTxt("022"));
        String line = errors.readLine();
        while (line != null) {
            printLogs(line);
            line = errors.readLine();
        }
        line = null;

        printLogs("------");
        printLogs(getLangTxt("023"));
        line = results.readLine();
        while (line != null) {
            printLogs(line);
            line = results.readLine();
        }
        printLogs("------");
        pro.destroy();
    }

    @Override
    public void run() {
        File froot = new File(this.dataDir.getAbsolutePath() + "/copyRootFilesTo.sh");
        File fhome = new File(this.dataDir.getAbsolutePath() + "/copyHomeFilesTo.sh");
        if (froot.exists() && fhome.exists()) {
            try {
                clearLogs();
                printLogs(getLangTxt("018"));
//                JAppToolKit.JRunHelper.runSysCmd("chmod +x " + froot.getAbsolutePath());
                JSudoTool.runSudoScript(froot.getAbsolutePath());
                progress.setValue(1);
                printLogs(getLangTxt("019"));
                runScriptWithOutput(fhome.getAbsolutePath());
                progress.setValue(2);
                printLogs(getLangTxt("020"));
                runScriptWithOutput(this.dataDir + "/" + this.config.getFinishScriptFile());
                progress.setValue(3);
                printLogs(getLangTxt("021"));

                this.btnNext.setText(getLangTxt("017"));
                this.btnNext.setEnabled(true);
            } catch (Exception ex) {
                ex.printStackTrace();
                javax.swing.JOptionPane.showMessageDialog(null, LanguageArrays.getLanguageText(currentLanguage, "001"));
                System.exit(0);
            }
        }
    }
}